/**
 * @file hoc.jsx.
 * @author liyyong18@baidu.com
 */
/* eslint fecs-indent: [0, "space", 2, 2] */

import * as React from 'react';
import {
  Component,
  PropTypes
} from "react";
import {findDOMNode} from 'react-dom';
import * as assign from 'object-assign';
import {render} from '../renderer';
import {Overlay} from 'react-bootstrap';
import SimplePopOver from '../../widgets/simple-popover/simple-popover';
import * as some from 'lodash/some';
import {getDialogContainer} from '../../util/helper';
import * as isPlainObject from 'lodash/isPlainObject';

import '../form/panel-form';

export const Enhance = ComposedComponent => class Searchable extends Component {
  constructor(props, context) {
    super(props, context);

    const form = this.buildSearchEditForm(props);
    this.state = {
      editing: false,
      form
    };

    this.openSearchEdit = this.openSearchEdit.bind(this);
    this.closeSearchEdit = this.closeSearchEdit.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.getOffset = this.getOffset.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    const props = this.props;

    if (props.value !== nextProps.value || props.quickEdit !== nextProps.quickEdit) {
      const form = this.buildSearchEditForm(nextProps);
      this.setState({
        form
      });
    }
  }

  buildSearchEditForm(props) {
    if (!props.searchable) {
      return null;
    }

    const {
      name,
      searchable,
      sortable
    } = props;

    let controls = searchable.controls ? searchable.controls : [
      assign({
        name,
        type: 'text'
      }, isPlainObject(searchable) ? searchable : null)
    ];

    if (sortable) {
      controls.unshift({
        name: "orderDir",
        type: 'button-group',
        btnClassName: "btn-default btn-sm",
        btnActiveClassName: "btn-default btn-sm active",
        options: [
          {
            label: "升序",
            value: "asc"
          },
          {
            label: "降序",
            value: "desc"
          }
        ]
      });
    }
    return {
      title: null,
      className: 'quick-edit-form',
      controls,
      actions: [
        {
          type: 'button',
          label: '取消'
        },

        {
          type: 'submit',
          className: 'btn-primary',
          label: '确认'
        }
      ]
    };
  }

  openSearchEdit() {
    this.setState({
      editing: !this.state.editing
    });
  }

  closeSearchEdit() {
    this.setState({
      editing: false
    });
  }

  handleSubmit(values) {
    const {
      onSearch,
      name,
      params
    } = this.props;

    if (values['orderDir']) {
      values['orderBy'] = name;
    }
    let changed = some(values, (value, key)=>{
      return value !== params[key]
    });
    this.closeSearchEdit();
    changed && onSearch(values);
  }

  getOffset(box, current) {
    const dom = findDOMNode(this).getBoundingClientRect();
    const windowWidth = window.innerWidth;
    let x = (box.width - dom.width) / 2;

    // 右边放不下,放左边.
    if (current.x + x + box.width > windowWidth) {
      x = (dom.width - box.width) / 2;
    }

    return {
      x: x - 1,
      y: -dom.height + 1
    }
  }

  render() {
    let {
      searchable,
      name,
      $path,
      disableSearch,
      affix,
      prefix
    } = this.props;

    const params = this.props.params || {};
    const editing = this.state.editing;

    if (searchable && name && !disableSearch) {

      let data = assign({}, params);
      let icon = editing || (<i className="fa fa-search" onClick={this.openSearchEdit} />);
      affix = affix ? (<div>{affix}{icon}</div>) : icon;

      if (params['orderBy'] != name) {
        delete data['orderBy'];
        delete data['orderDir'];
      }

      if (editing) {
        const sharedProps = {
          container: getDialogContainer(),
          show: true,
          placement: 'bottom',
          target: () => findDOMNode(this),
          rootClose: true,
          onHide: this.closeSearchEdit
        };

        let overlay = (
          <Overlay {...sharedProps}>
            <SimplePopOver className="quick-edit-popover" offset={this.getOffset}>
              {render(`${$path}/quick-edit/panel-form`, this.state.form, {
                data,
                formRef: form => this.form = form,
                onRequestAction: btn => btn.type === 'submit' ? this.form.submit() :  this.closeSearchEdit(),
                onSubmit: this.handleSubmit
              })}
            </SimplePopOver>
          </Overlay>
        );

        prefix = prefix ? (<div>{prefix}{overlay}</div>) : overlay;
      }
    }

    return (
      <ComposedComponent {...this.props} editing={editing} prefix={prefix} affix={affix} />
    )
  }
};

export default Enhance;